deltas: Prune deltas when the corresponding "to" commit vanishes
authorColin Walters <walters@verbum.org>
Mon, 2 Feb 2015 18:04:52 +0000 (13:04 -0500)
committerColin Walters <walters@verbum.org>
Mon, 16 Feb 2015 15:10:35 +0000 (10:10 -0500)
We want prune to actually give you back disk space when using deltas.

src/libostree/ostree-core-private.h
src/libostree/ostree-core.c
src/libostree/ostree-repo-prune.c
src/libostree/ostree-repo-pull.c
src/libostree/ostree-repo-static-delta-compilation.c
src/libostree/ostree-repo.c
tests/test-delta.sh

index 402cc5d71d41c06616f28b99bd18c4a1af889a5f..8d6cb93ba311dac1e3f0db84c857b0c2c1f5228e 100644 (file)
@@ -96,7 +96,12 @@ _ostree_get_relative_object_path (const char        *checksum,
 
 char *
 _ostree_get_relative_static_delta_path (const char        *from,
-                                        const char        *to);
+                                        const char        *to,
+                                        const char        *target);
+
+char *
+_ostree_get_relative_static_delta_superblock_path (const char        *from,
+                                                   const char        *to);
 
 char *
 _ostree_get_relative_static_delta_detachedmeta_path (const char        *from,
index 570e8199d75a2e4ca74a1ca25bb6afebc8d26ceb..6a72251e9b8d70cb751ef9ec6c72ee5326033ebc 100644 (file)
@@ -1425,15 +1425,15 @@ _ostree_get_relative_object_path (const char         *checksum,
   return g_string_free (path, FALSE);
 }
 
-static char *
-get_delta_path (const char *from,
-                const char *to,
-                const char *target)
+char *
+_ostree_get_relative_static_delta_path (const char *from,
+                                        const char *to,
+                                        const char *target)
 {
-  char prefix[3];
   guint8 csum_to[32];
   char to_b64[44];
   guint8 csum_to_copy[32];
+  GString *ret = g_string_new ("deltas/");
 
   ostree_checksum_inplace_to_bytes (to, csum_to);
   ostree_checksum_b64_inplace_from_bytes (csum_to, to_b64);
@@ -1441,14 +1441,7 @@ get_delta_path (const char *from,
 
   g_assert (memcmp (csum_to, csum_to_copy, 32) == 0);
 
-  if (from == NULL)
-    {
-      prefix[0] = to_b64[0];
-      prefix[1] = to_b64[1];
-      prefix[2] = '\0';
-      return g_strconcat ("deltas/", prefix, "/", ((char*)to_b64)+2, "/", target, NULL);
-    }
-  else
+  if (from != NULL)
     {
       guint8 csum_from[32];
       char from_b64[44];
@@ -1456,25 +1449,40 @@ get_delta_path (const char *from,
       ostree_checksum_inplace_to_bytes (from, csum_from);
       ostree_checksum_b64_inplace_from_bytes (csum_from, from_b64);
 
-      prefix[0] = from_b64[0];
-      prefix[1] = from_b64[1];
-      prefix[2] = '\0';
-      return g_strconcat ("deltas/", prefix, "/", ((char*)from_b64)+2, "-", to_b64, "/", target, NULL);
+      g_string_append_c (ret, from_b64[0]);
+      g_string_append_c (ret, from_b64[1]);
+      g_string_append_c (ret, '/');
+      g_string_append (ret, from_b64 + 2);
+      g_string_append_c (ret, '-');
     }
+
+  g_string_append_c (ret, to_b64[0]);
+  g_string_append_c (ret, to_b64[1]);
+  if (from == NULL)
+    g_string_append_c (ret, '/');
+  g_string_append (ret, to_b64 + 2);
+
+  if (target != NULL)
+    {
+      g_string_append_c (ret, '/');
+      g_string_append (ret, target);
+    }
+  
+  return g_string_free (ret, FALSE);
 }
 
 char *
-_ostree_get_relative_static_delta_path (const char        *from,
-                                        const char        *to)
+_ostree_get_relative_static_delta_superblock_path (const char        *from,
+                                                   const char        *to)
 {
-  return get_delta_path (from, to, "superblock");
+  return _ostree_get_relative_static_delta_path (from, to, "superblock");
 }
 
 char *
 _ostree_get_relative_static_delta_detachedmeta_path (const char        *from,
                                                      const char        *to)
 {
-  return get_delta_path (from, to, "meta");
+  return _ostree_get_relative_static_delta_path (from, to, "meta");
 }
 
 char *
@@ -1483,7 +1491,7 @@ _ostree_get_relative_static_delta_part_path (const char        *from,
                                              guint              i)
 {
   gs_free char *partstr = g_strdup_printf ("%u", i);
-  return get_delta_path (from, to, partstr);
+  return _ostree_get_relative_static_delta_path (from, to, partstr);
 }
 
 /*
index 05ba43a1777c87b8f87b87a3f0510c54029823b4..cff2f600cf05184ac43be21209f754a476ee0a35 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "ostree-core-private.h"
 #include "ostree-repo-private.h"
 #include "otutil.h"
 
@@ -212,6 +213,49 @@ ostree_repo_prune (OstreeRepo        *self,
                                      cancellable, error))
         goto out;
     }
+
+  { gs_unref_ptrarray GPtrArray *deltas = NULL;
+    guint i;
+
+    if (!ostree_repo_list_static_delta_names (self, &deltas,
+                                              cancellable, error))
+      goto out;
+
+    for (i = 0; i < deltas->len; i++)
+      {
+        const char *deltaname = deltas->pdata[i];
+        const char *dash = strchr (deltaname, '-');
+        const char *to = NULL;
+        gboolean have_commit;
+        gs_free char *from = NULL;
+        gs_free char *deltadir = NULL;
+
+        if (!dash)
+          {
+            to = deltaname;
+          }
+        else
+          {
+            from = g_strndup (deltaname, dash - deltaname);
+            to = dash + 1;
+          }
+
+        if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT,
+                                     to, &have_commit,
+                                     cancellable, error))
+          goto out;
+
+        if (have_commit)
+          continue;
+
+        deltadir = _ostree_get_relative_static_delta_path (from, to, NULL);
+
+        if (!gs_shutil_rm_rf_at (self->repo_dir_fd, deltadir,
+                                 cancellable, error))
+          goto out;
+      }
+  }
+
   ret = TRUE;
   *out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta +
                         data.n_reachable_content + data.n_unreachable_content);
index daf61377a50e1aa6ab318d0777f6042bcce0ef7c..5d359672304b3b77ba47c68b6c00be45db9a3fd4 100644 (file)
@@ -1340,7 +1340,8 @@ request_static_delta_superblock_sync (OtPullData  *pull_data,
 {
   gboolean ret = FALSE;
   gs_unref_variant GVariant *ret_delta_superblock = NULL;
-  gs_free char *delta_name = _ostree_get_relative_static_delta_path (from_revision, to_revision);
+  gs_free char *delta_name =
+    _ostree_get_relative_static_delta_superblock_path (from_revision, to_revision);
   gs_unref_bytes GBytes *delta_superblock_data = NULL;
   gs_unref_bytes GBytes *delta_meta_data = NULL;
   gs_unref_variant GVariant *delta_superblock = NULL;
index 594b432fe30cd02b2867175aa431901ed7b72bd4..62d006ef888ac90094ee7ca8e0a71810bc2b1b00 100644 (file)
@@ -1122,7 +1122,7 @@ ostree_repo_static_delta_generate (OstreeRepo                   *self,
                   part_builder->uncompressed_size);
     }
 
-  descriptor_relpath = _ostree_get_relative_static_delta_path (from, to);
+  descriptor_relpath = _ostree_get_relative_static_delta_superblock_path (from, to);
   descriptor_path = g_file_resolve_relative_path (self->repodir, descriptor_relpath);
   descriptor_dir = g_file_get_parent (descriptor_path);
 
index 7e01bb39e206e206eba1d5761bc20d2366c6531d..85792d880e719b3f7464d3124795687d8057a207 100644 (file)
@@ -3209,7 +3209,7 @@ ostree_repo_sign_delta (OstreeRepo     *self,
     _ostree_get_relative_static_delta_detachedmeta_path (from_commit, to_commit);
   detached_metadata_path = g_file_resolve_relative_path (self->repodir, detached_metadata_relpath);
 
-  delta_path = _ostree_get_relative_static_delta_path (from_commit, to_commit);
+  delta_path = _ostree_get_relative_static_delta_superblock_path (from_commit, to_commit);
   delta_file = g_file_resolve_relative_path (self->repodir, delta_path);
   delta_data = gs_file_map_readonly (delta_file, cancellable, error);
   if (!delta_data)
index 988d7ab60ad1c853715854fc5743d3bea650a96b..f5bb802c830ab8ade821db776aac93589571bfde 100755 (executable)
@@ -59,6 +59,8 @@ origrev=$(ostree --repo=repo rev-parse test)
 
 ostree --repo=repo static-delta generate --empty --to=${origrev}
 ostree --repo=repo static-delta list | grep ${origrev} || exit 1
+ostree --repo=repo prune
+ostree --repo=repo static-delta list | grep ${origrev} || exit 1
 
 permuteDirectory 1 files
 ostree --repo=repo commit -b test -s test --tree=dir=files